home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / nasm095s.zip / NASMLIB.C < prev    next >
C/C++ Source or Header  |  1997-07-27  |  12KB  |  544 lines

  1. /* nasmlib.c    library routines for the Netwide Assembler
  2.  *
  3.  * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
  4.  * Julian Hall. All rights reserved. The software is
  5.  * redistributable under the licence given in the file "Licence"
  6.  * distributed in the NASM archive.
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <ctype.h>
  13.  
  14. #include "nasm.h"
  15. #include "nasmlib.h"
  16.  
  17. static efunc nasm_malloc_error;
  18.  
  19. #ifdef LOGALLOC
  20. static FILE *logfp;
  21. #endif
  22.  
  23. void nasm_set_malloc_error (efunc error) {
  24.     nasm_malloc_error = error;
  25. #ifdef LOGALLOC
  26.     logfp = fopen ("malloc.log", "w");
  27.     setvbuf (logfp, NULL, _IOLBF, BUFSIZ);
  28.     fprintf (logfp, "null pointer is %p\n", NULL);
  29. #endif
  30. }
  31.  
  32. #ifdef LOGALLOC
  33. void *nasm_malloc_log (char *file, int line, size_t size)
  34. #else
  35. void *nasm_malloc (size_t size)
  36. #endif
  37. {
  38.     void *p = malloc(size);
  39.     if (!p)
  40.     nasm_malloc_error (ERR_FATAL | ERR_NOFILE, "out of memory");
  41. #ifdef LOGALLOC
  42.     else
  43.     fprintf(logfp, "%s %d malloc(%ld) returns %p\n",
  44.         file, line, (long)size, p);
  45. #endif
  46.     return p;
  47. }
  48.  
  49. #ifdef LOGALLOC
  50. void *nasm_realloc_log (char *file, int line, void *q, size_t size)
  51. #else
  52. void *nasm_realloc (void *q, size_t size)
  53. #endif
  54. {
  55.     void *p = q ? realloc(q, size) : malloc(size);
  56.     if (!p)
  57.     nasm_malloc_error (ERR_FATAL | ERR_NOFILE, "out of memory");
  58. #ifdef LOGALLOC
  59.     else if (q)
  60.     fprintf(logfp, "%s %d realloc(%p,%ld) returns %p\n",
  61.         file, line, q, (long)size, p);
  62.     else
  63.     fprintf(logfp, "%s %d malloc(%ld) returns %p\n",
  64.         file, line, (long)size, p);
  65. #endif
  66.     return p;
  67. }
  68.  
  69. #ifdef LOGALLOC
  70. void nasm_free_log (char *file, int line, void *q)
  71. #else
  72. void nasm_free (void *q)
  73. #endif
  74. {
  75.     if (q) {
  76.     free (q);
  77. #ifdef LOGALLOC
  78.     fprintf(logfp, "%s %d free(%p)\n",
  79.         file, line, q);
  80. #endif
  81.     }
  82. }
  83.  
  84. #ifdef LOGALLOC
  85. char *nasm_strdup_log (char *file, int line, char *s)
  86. #else
  87. char *nasm_strdup (char *s)
  88. #endif
  89. {
  90.     char *p;
  91.     int size = strlen(s)+1;
  92.  
  93.     p = malloc(size);
  94.     if (!p)
  95.     nasm_malloc_error (ERR_FATAL | ERR_NOFILE, "out of memory");
  96. #ifdef LOGALLOC
  97.     else
  98.     fprintf(logfp, "%s %d strdup(%ld) returns %p\n",
  99.         file, line, (long)size, p);
  100. #endif
  101.     strcpy (p, s);
  102.     return p;
  103. }
  104.  
  105. int nasm_stricmp (char *s1, char *s2) {
  106.     while (*s1 && toupper(*s1) == toupper(*s2))
  107.     s1++, s2++;
  108.     if (!*s1 && !*s2)
  109.     return 0;
  110.     else if (toupper(*s1) < toupper(*s2))
  111.     return -1;
  112.     else
  113.     return 1;
  114. }
  115.  
  116. int nasm_strnicmp (char *s1, char *s2, int n) {
  117.     while (n > 0 && *s1 && toupper(*s1) == toupper(*s2))
  118.     s1++, s2++, n--;
  119.     if ((!*s1 && !*s2) || n==0)
  120.     return 0;
  121.     else if (toupper(*s1) < toupper(*s2))
  122.     return -1;
  123.     else
  124.     return 1;
  125. }
  126.  
  127. #define lib_isnumchar(c)   ( isalnum(c) || (c) == '$')
  128. #define numvalue(c)  ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0')
  129.  
  130. long readnum (char *str, int *error) {
  131.     char *r = str, *q;
  132.     long radix;
  133.     long result;
  134.  
  135.     *error = FALSE;
  136.  
  137.     while (isspace(*r)) r++;           /* find start of number */
  138.     q = r;
  139.  
  140.     while (lib_isnumchar(*q)) q++;     /* find end of number */
  141.  
  142.     /*
  143.      * If it begins 0x, 0X or $, or ends in H, it's in hex. if it
  144.      * ends in Q, it's octal. if it ends in B, it's binary.
  145.      * Otherwise, it's ordinary decimal.
  146.      */
  147.     if (*r=='0' && (r[1]=='x' || r[1]=='X'))
  148.     radix = 16, r += 2;
  149.     else if (*r=='$')
  150.     radix = 16, r++;
  151.     else if (q[-1]=='H' || q[-1]=='h')
  152.     radix = 16 , q--;
  153.     else if (q[-1]=='Q' || q[-1]=='q')
  154.     radix = 8 , q--;
  155.     else if (q[-1]=='B' || q[-1]=='b')
  156.     radix = 2 , q--;
  157.     else
  158.     radix = 10;
  159.  
  160.     result = 0;
  161.     while (*r && r < q) {
  162.     if (*r<'0' || (*r>'9' && *r<'A') || numvalue(*r)>=radix) {
  163.         *error = TRUE;
  164.         return 0;
  165.     }
  166.     result = radix * result + numvalue(*r);
  167.     r++;
  168.     }
  169.     return result;
  170. }
  171.  
  172. static long next_seg;
  173.  
  174. void seg_init(void) {
  175.     next_seg = 0;
  176. }
  177.  
  178. long seg_alloc(void) {
  179.     return (next_seg += 2) - 2;
  180. }
  181.  
  182. void fwriteshort (int data, FILE *fp) {
  183.     fputc ((int) (data & 255), fp);
  184.     fputc ((int) ((data >> 8) & 255), fp);
  185. }
  186.  
  187. void fwritelong (long data, FILE *fp) {
  188.     fputc ((int) (data & 255), fp);
  189.     fputc ((int) ((data >> 8) & 255), fp);
  190.     fputc ((int) ((data >> 16) & 255), fp);
  191.     fputc ((int) ((data >> 24) & 255), fp);
  192. }
  193.  
  194. void standard_extension (char *inname, char *outname, char *extension,
  195.              efunc error) {
  196.     char *p, *q;
  197.  
  198.     q = inname;
  199.     p = outname;
  200.     while (*q) *p++ = *q++;           /* copy, and find end of string */
  201.     *p = '\0';                   /* terminate it */
  202.     while (p > outname && *--p != '.');/* find final period (or whatever) */
  203.     if (*p != '.') while (*p) p++;     /* go back to end if none found */
  204.     if (!strcmp(p, extension)) {       /* is the extension already there? */
  205.     if (*extension)
  206.         error(ERR_WARNING | ERR_NOFILE,
  207.           "file name already ends in `%s': "
  208.           "output will be in `nasm.out'",
  209.           extension);
  210.     else
  211.         error(ERR_WARNING | ERR_NOFILE,
  212.           "file name already has no extension: "
  213.           "output will be in `nasm.out'");
  214.     strcpy(outname, "nasm.out");
  215.     } else
  216.     strcpy(p, extension);
  217. }
  218.  
  219. #define RAA_BLKSIZE 4096           /* this many longs allocated at once */
  220. #define RAA_LAYERSIZE 1024           /* this many _pointers_ allocated */
  221.  
  222. typedef struct RAA RAA;
  223. typedef union RAA_UNION RAA_UNION;
  224. typedef struct RAA_LEAF RAA_LEAF;
  225. typedef struct RAA_BRANCH RAA_BRANCH;
  226.  
  227. struct RAA {
  228.     int layers;
  229.     long stepsize;
  230.     union RAA_UNION {
  231.     struct RAA_LEAF {
  232.         long data[RAA_BLKSIZE];
  233.     } l;
  234.     struct RAA_BRANCH {
  235.         struct RAA *data[RAA_LAYERSIZE];
  236.     } b;
  237.     } u;
  238. };
  239.  
  240. #define LEAFSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_LEAF))
  241. #define BRANCHSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH))
  242.  
  243. #define LAYERSIZ(r) ( (r)->layers==0 ? RAA_BLKSIZE : RAA_LAYERSIZE )
  244.  
  245. static struct RAA *real_raa_init (int layers) {
  246.     struct RAA *r;
  247.  
  248.     if (layers == 0) {
  249.     r = nasm_malloc (LEAFSIZ);
  250.     memset (r->u.l.data, 0, sizeof(r->u.l.data));
  251.     r->layers = 0;
  252.     r->stepsize = 1L;
  253.     } else {
  254.     r = nasm_malloc (BRANCHSIZ);
  255.     memset (r->u.b.data, 0, sizeof(r->u.b.data));
  256.     r->layers = layers;
  257.     r->stepsize = 1L;
  258.     while (layers--)
  259.         r->stepsize *= RAA_LAYERSIZE;
  260.     }
  261.     return r;
  262. }
  263.  
  264. struct RAA *raa_init (void) {
  265.     return real_raa_init (0);
  266. }
  267.  
  268. void raa_free (struct RAA *r) {
  269.     if (r->layers == 0)
  270.     nasm_free (r);
  271.     else {
  272.     struct RAA **p;
  273.     for (p = r->u.b.data; p - r->u.b.data < RAA_LAYERSIZE; p++)
  274.         if (*p)
  275.         raa_free (*p);
  276.     }
  277. }
  278.  
  279. long raa_read (struct RAA *r, long posn) {
  280.     if (posn > r->stepsize * LAYERSIZ(r))
  281.     return 0L;
  282.     while (r->layers > 0) {
  283.     ldiv_t l;
  284.     l = ldiv (posn, r->stepsize);
  285.     r = r->u.b.data[l.quot];
  286.     posn = l.rem;
  287.     if (!r)                   /* better check this */
  288.         return 0L;
  289.     }
  290.     return r->u.l.data[posn];
  291. }
  292.  
  293. struct RAA *raa_write (struct RAA *r, long posn, long value) {
  294.     struct RAA *result;
  295.  
  296.     if (posn < 0)
  297.     nasm_malloc_error (ERR_PANIC, "negative position in raa_write");
  298.  
  299.     while (r->stepsize * LAYERSIZ(r) < posn) {
  300.     /*
  301.      * Must go up a layer.
  302.      */
  303.     struct RAA *s;
  304.  
  305.     s = nasm_malloc (BRANCHSIZ);
  306.     memset (s->u.b.data, 0, sizeof(r->u.b.data));
  307.     s->layers = r->layers + 1;
  308.     s->stepsize = RAA_LAYERSIZE * r->stepsize;
  309.     s->u.b.data[0] = r;
  310.     r = s;
  311.     }
  312.  
  313.     result = r;
  314.  
  315.     while (r->layers > 0) {
  316.     ldiv_t l;
  317.     struct RAA **s;
  318.     l = ldiv (posn, r->stepsize);
  319.     s = &r->u.b.data[l.quot];
  320.     if (!*s)
  321.         *s = real_raa_init (r->layers - 1);
  322.     r = *s;
  323.     posn = l.rem;
  324.     }
  325.  
  326.     r->u.l.data[posn] = value;
  327.  
  328.     return result;
  329. }
  330.  
  331. #define SAA_MAXLEN 8192
  332.  
  333. struct SAA {
  334.     /*
  335.      * members `end' and `elem_len' are only valid in first link in
  336.      * list; `rptr' and `rpos' are used for reading
  337.      */
  338.     struct SAA *next, *end, *rptr;
  339.     long elem_len, length, posn, start, rpos;
  340.     char *data;
  341. };
  342.  
  343. struct SAA *saa_init (long elem_len) {
  344.     struct SAA *s;
  345.  
  346.     if (elem_len > SAA_MAXLEN)
  347.     nasm_malloc_error (ERR_PANIC | ERR_NOFILE, "SAA with huge elements");
  348.  
  349.     s = nasm_malloc (sizeof(struct SAA));
  350.     s->posn = s->start = 0L;
  351.     s->elem_len = elem_len;
  352.     s->length = SAA_MAXLEN - (SAA_MAXLEN % elem_len);
  353.     s->data = nasm_malloc (s->length);
  354.     s->next = NULL;
  355.     s->end = s;
  356.  
  357.     return s;
  358. }
  359.  
  360. void saa_free (struct SAA *s) {
  361.     struct SAA *t;
  362.  
  363.     while (s) {
  364.     t = s->next;
  365.     nasm_free (s->data);
  366.     nasm_free (s);
  367.     s = t;
  368.     }
  369. }
  370.  
  371. void *saa_wstruct (struct SAA *s) {
  372.     void *p;
  373.  
  374.     if (s->end->length - s->end->posn < s->elem_len) {
  375.     s->end->next = nasm_malloc (sizeof(struct SAA));
  376.     s->end->next->start = s->end->start + s->end->posn;
  377.     s->end = s->end->next;
  378.     s->end->length = s->length;
  379.     s->end->next = NULL;
  380.     s->end->posn = 0L;
  381.     s->end->data = nasm_malloc (s->length);
  382.     }
  383.  
  384.     p = s->end->data + s->end->posn;
  385.     s->end->posn += s->elem_len;
  386.     return p;
  387. }
  388.  
  389. void saa_wbytes (struct SAA *s, void *data, long len) {
  390.     char *d = data;
  391.  
  392.     while (len > 0) {
  393.     long l = s->end->length - s->end->posn;
  394.     if (l > len)
  395.         l = len;
  396.     if (l > 0) {
  397.         if (d) {
  398.         memcpy (s->end->data + s->end->posn, d, l);
  399.         d += l;
  400.         } else
  401.         memset (s->end->data + s->end->posn, 0, l);
  402.         s->end->posn += l;
  403.         len -= l;
  404.     }
  405.     if (len > 0) {
  406.         s->end->next = nasm_malloc (sizeof(struct SAA));
  407.         s->end->next->start = s->end->start + s->end->posn;
  408.         s->end = s->end->next;
  409.         s->end->length = s->length;
  410.         s->end->next = NULL;
  411.         s->end->posn = 0L;
  412.         s->end->data = nasm_malloc (s->length);
  413.     }
  414.     }
  415. }
  416.  
  417. void saa_rewind (struct SAA *s) {
  418.     s->rptr = s;
  419.     s->rpos = 0L;
  420. }
  421.  
  422. void *saa_rstruct (struct SAA *s) {
  423.     void *p;
  424.  
  425.     if (!s->rptr)
  426.     return NULL;
  427.  
  428.     if (s->rptr->posn - s->rpos < s->elem_len) {
  429.     s->rptr = s->rptr->next;
  430.     if (!s->rptr)
  431.         return NULL;           /* end of array */
  432.     s->rpos = 0L;
  433.     }
  434.  
  435.     p = s->rptr->data + s->rpos;
  436.     s->rpos += s->elem_len;
  437.     return p;
  438. }
  439.  
  440. void *saa_rbytes (struct SAA *s, long *len) {
  441.     void *p;
  442.  
  443.     if (!s->rptr)
  444.     return NULL;
  445.  
  446.     p = s->rptr->data + s->rpos;
  447.     *len = s->rptr->posn - s->rpos;
  448.     s->rptr = s->rptr->next;
  449.     s->rpos = 0L;
  450.     return p;
  451. }
  452.  
  453. void saa_rnbytes (struct SAA *s, void *data, long len) {
  454.     char *d = data;
  455.  
  456.     while (len > 0) {
  457.     long l;
  458.  
  459.     if (!s->rptr)
  460.         return;
  461.  
  462.     l = s->rptr->posn - s->rpos;
  463.     if (l > len)
  464.         l = len;
  465.     if (l > 0) {
  466.         memcpy (d, s->rptr->data + s->rpos, l);
  467.         d += l;
  468.         s->rpos += l;
  469.         len -= l;
  470.     }
  471.     if (len > 0) {
  472.         s->rptr = s->rptr->next;
  473.         s->rpos = 0L;
  474.     }
  475.     }
  476. }
  477.  
  478. void saa_fread (struct SAA *s, long posn, void *data, long len) {
  479.     struct SAA *p;
  480.     long pos;
  481.     char *cdata = data;
  482.  
  483.     if (!s->rptr || posn > s->rptr->start + s->rpos)
  484.     saa_rewind (s);
  485.     while (posn >= s->rptr->start + s->rptr->posn) {
  486.     s->rptr = s->rptr->next;
  487.     if (!s->rptr)
  488.         return;               /* what else can we do?! */
  489.     }
  490.  
  491.     p = s->rptr;
  492.     pos = posn - s->rptr->start;
  493.     while (len) {
  494.     long l = s->rptr->posn - pos;
  495.     if (l > len)
  496.         l = len;
  497.     memcpy (cdata, s->rptr->data+pos, l);
  498.     len -= l;
  499.     cdata += l;
  500.     p = p->next;
  501.     if (!p)
  502.         return;
  503.     pos = 0L;
  504.     }
  505. }
  506.  
  507. void saa_fwrite (struct SAA *s, long posn, void *data, long len) {
  508.     struct SAA *p;
  509.     long pos;
  510.     char *cdata = data;
  511.  
  512.     if (!s->rptr || posn > s->rptr->start + s->rpos)
  513.     saa_rewind (s);
  514.     while (posn >= s->rptr->start + s->rptr->posn) {
  515.     s->rptr = s->rptr->next;
  516.     if (!s->rptr)
  517.         return;               /* what else can we do?! */
  518.     }
  519.  
  520.     p = s->rptr;
  521.     pos = posn - s->rptr->start;
  522.     while (len) {
  523.     long l = s->rptr->posn - pos;
  524.     if (l > len)
  525.         l = len;
  526.     memcpy (s->rptr->data+pos, cdata, l);
  527.     len -= l;
  528.     cdata += l;
  529.     p = p->next;
  530.     if (!p)
  531.         return;
  532.     pos = 0L;
  533.     }
  534. }
  535.  
  536. void saa_fpwrite (struct SAA *s, FILE *fp) {
  537.     char *data;
  538.     long len;
  539.  
  540.     saa_rewind (s);
  541.     while ( (data = saa_rbytes (s, &len)) )
  542.     fwrite (data, 1, len, fp);
  543. }
  544.